/*
* @file    :task_monitor.c
* @module  :MONITOR TASK
* @author  :LingFengLu
* @date    :2023-06-08
*/

#include "task_monitor.h"
#include "task_glucose.h"
#include "task.h"
#include "task_comm.h"
#include "mid.h"
#include "lib_string.h"
#include "lib_queue.h"
//Constant definition    宏定义
#define HISTORY_BUFFER_SIZE                 8
#define OPERATE_RECORD_BUFFER_SIZE          4
#define UPDATE_DELAY					    10
#define UPDATE_DELAY_LONG                   300

#define MAX_HISTORIES_LENGTH                120
#define STATUS_SIZE                         TASK_COMM_BROADCAST_DATA_SIZE
#define STATUS_BATTERY_OFFSET               0
#define STATUS_CURRENT_TIME_OFFSET          1
#define STATUS_HISTORY_OFFSET               2
#define STATUS_DATETIME_OFFSET              2
#define STATUS_TYPE_OFFSET                  9
#define STATUS_VALUE_OFFSET                 10


// #define MINUTE_PER_HOUR						60
// #define SECOND_PER_MINUTE					60
//Type definition    类型定义
typedef enum
{
	TASK_MONITOR_FLAG_BUSY = 0,
	TASK_MONITOR_FLAG_BLANK,
	TASK_MONITOR_FLAG_ERROR,
	TASK_MONITOR_COUNT_FLAG
} task_monitor_flag;

//Global variable definition    全局变量定义


//Private variable definition    私有变量定义
static lib_queue_object m_t_QueueHistory = {0};
static history m_t_HistoryBuffer[HISTORY_BUFFER_SIZE] = {0};
static lib_queue_object m_t_QueueOperateRecord = {0};
static operate_record m_t_OperateRecordBuffer[OPERATE_RECORD_BUFFER_SIZE] ={0};

static uint m_ui_HistoryBufferCount = 0;
static history_header m_t_HistoryHeader = {0};
static history m_t_History = {0};
static operate_record_header m_t_OperateRecordHeader ={0};
static operate_record m_t_OperateRecord ={0};
static sint32 m_s32_RunningTime = 0;
static uint m_ui_Flag = 0;
static uint8 m_u8_Status[STATUS_SIZE] = {0};
static uint m_ui_UpdateNow = FUNCTION_FAIL;

static const uint m_ui_ParameterSize[TASK_MONITOR_COUNT_PARAM] =
{
	sizeof(uint32),
	sizeof(history) - ( sizeof(sensor_param) - sizeof(uint16) ),
	0,
	sizeof(uint),
	sizeof(uint16),
	sizeof(uint),
	sizeof(sensor_param),
	sizeof(history),
	sizeof(history),
	sizeof(sint32),
	sizeof(sint32),
	sizeof(uint),
	sizeof(uint),
};
//Private function declaration   私有函数申明

static void TaskMonitor_LoadHistoryHead(void);
static void TaskMonitor_ResetHistoryHead(void);
static void TaskMonitor_CheckHistoryHead(void);
static void TaskMonitor_SaveHistoryHead(void);
static uint TaskMonitor_LoadHistory
(
uint16 u16_Index,
history * tp_History
);
static uint TaskMonitor_LoadHistories
( 
uint16 u16_Index,
uint8 *u8p_Data,
uint *uip_Length,
uint ui_RawData 
);
static void TaskMonitor_InitHistory(void);

static void TaskMonitor_LoadOperateRecordHead(void);
static void TaskMonitor_SaveOperateRecordHead(void);
static uint TaskMonitor_LoadOpearte
(
uint16 u16_Index,
operate_record * tp_OperateRecord
);
static void TaskMonitor_OperateRecord(void);
static void TaskMonitor_UpdateDateTime
( 
uint16 u16_ClockTime
);
static void TaskMonitor_UpdateHistory
( 
uint16 u16_ClockTime
);
static uint TaskMonitor_SaveHistory
(
history * tp_History
);
static void TaskMonitor_UpdateOperateRecord
( 
uint16 u16_ClockTime
);
uint TaskMonitor_UpdateBattery(void);
static void TaskMonitor_Update
( 
uint16 u16_ClockTime 
);
static void TaskMonitor_UpdateBroadcast(void);
//Public function definition   公共函数定义
void TaskMonitor_Init
(
devos_task_handle t_TaskHandle
)
{
	LibQueue_Initialize( &m_t_QueueHistory,
			    (uint8 *)m_t_HistoryBuffer,
			    sizeof(history)*HISTORY_BUFFER_SIZE) ;
	
	LibQueue_Initialize( &m_t_QueueOperateRecord,
			    (uint8 *)m_t_OperateRecordBuffer,
			    sizeof(operate_record)*OPERATE_RECORD_BUFFER_SIZE) ;
	
	TaskMonitor_InitHistory();
	TaskMonitor_OperateRecord();
	
}


void TaskMonitor_Process
(
devos_task_handle t_TaskHandle
)
{
	static uint8 *u8p_MessageData;
	static devos_int t_MessageLength;
	static uint16 u16_ClockTime;
	DEVOS_TASK_BEGIN
		
		DevOS_MessageWait(TASK_MESSAGE_ID_CLOCK, u8p_MessageData, &t_MessageLength);
	LOG_INFO("TaskMonitor_Process");
	REG_SET_BIT(m_ui_Flag, TASK_MONITOR_FLAG_BUSY);
	u16_ClockTime = *((const uint16 *)u8p_MessageData)/MILLISECOND_PER_SECOND;
	m_s32_RunningTime += (sint32)(u16_ClockTime);

	TaskMonitor_Update(u16_ClockTime);
	REG_CLEAR_BIT(m_ui_Flag, TASK_MONITOR_FLAG_BUSY);
	DEVOS_TASK_END
}

uint TaskMonitor_SetConfig
(
uint ui_Parameter,
const uint8 *u8p_Value,
uint ui_Length
)
{    
	sint32 s32_Value;
	if (ui_Length != m_ui_ParameterSize[ui_Parameter])
		return FUNCTION_FAIL;
	switch (ui_Parameter)
	{
	    case TASK_MONITOR_PARAM_DATE_TIME:
		s32_Value = *(const sint32 *)u8p_Value;
		TaskGlucose_SkipDelay( s32_Value - m_t_History.s32_DateTime );
		
		m_t_OperateRecord.s32_DateTime = s32_Value;
		TaskMonitor_SetEventLog( OPERATE_SET_TIME );
		
		m_t_History.s32_DateTime = s32_Value;
		s32_Value = m_t_History.s32_DateTime / 10 * 10;
		Lib_Memcpy( m_u8_Status + STATUS_DATETIME_OFFSET,
			   (const uint8 *)&s32_Value,
			   sizeof(s32_Value) );
		m_u8_Status[STATUS_CURRENT_TIME_OFFSET] = 0;
		TaskMonitor_UpdateBroadcast();
		break;
	    case TASK_MONITOR_PARAM_RUNNING_TIME:
		*((sint32 *)u8p_Value) = (uint)m_t_HistoryHeader.s32_RunningTime;
		break;
	    case TASK_MONITOR_PARAM_OPTIONAL_STATUS:
		Lib_Memcpy( (uint8 *)&m_t_History.t_Parameter,
			   u8p_Value,
			   ui_Length );
		break;
	    case TASK_MONITOR_PARAM_UPDATE_SWITCH:
		if (*((uint *)u8p_Value) != 0)
			REG_CLEAR_BIT(m_ui_Flag, TASK_MONITOR_FLAG_BLANK);
		else
			REG_SET_BIT(m_ui_Flag, TASK_MONITOR_FLAG_BLANK);
		break;
		
	    case TASK_MONITOR_PARAM_UPDATE_BROADCAST:
		if (*((uint *)u8p_Value) != 0)
			TaskMonitor_UpdateBroadcast();
		break;
		
		
	    default:
		return FUNCTION_FAIL;
	}
	return FUNCTION_OK;
}
uint TaskMonitor_GetConfig
(
uint ui_Parameter,
uint8 *u8p_Value,
uint *uip_Length
)
{
	sint32 s32_Value;
	switch (ui_Parameter)
	{
		
		
	    case TASK_MONITOR_PARAM_START_TIME:
		*((sint32 *)u8p_Value) = m_t_HistoryHeader.s32_StartTime;
		break;
		
	    case TASK_MONITOR_PARAM_DATE_TIME:
		*((sint32 *)u8p_Value) = m_t_History.s32_DateTime;
		break;
		
	    case TASK_MONITOR_PARAM_RUNNING_TIME:
		*((sint32 *)u8p_Value) = (uint)m_t_HistoryHeader.s32_RunningTime;
		break;
		
	    case TASK_MONITOR_PARAM_ELAPSED_TIME:
		s32_Value = m_t_History.s32_DateTime - m_t_HistoryHeader.s32_StartTime;
		if (s32_Value < 0)
			s32_Value = 0;
		*((uint *)u8p_Value) = (uint)s32_Value;
		break;
		
	    case TASK_MONITOR_PARAM_HISTORY:
		if ((*((uint16 *)u8p_Value) == 0))
			*((uint16 *)u8p_Value) = m_t_HistoryHeader.u16_Index;
		if ( TaskMonitor_LoadHistory( *((uint16 *)u8p_Value),
					     (history *)u8p_Value ) != FUNCTION_OK )
			return FUNCTION_FAIL;
		break;
		
	    case TASK_MONITOR_PARAM_BUSY:
		if (REG_GET_BIT(m_ui_Flag, TASK_MONITOR_FLAG_BUSY) != 0)
			*((uint *)u8p_Value) = 1;
		else
			*((uint *)u8p_Value) = 0;
		break;
		
	    case TASK_MONITOR_PARAM_HISTORIES_FULL:
		if ((*((uint16 *)u8p_Value) == 0))
			*((uint16 *)u8p_Value) = m_t_HistoryHeader.u16_Index;
		return TaskMonitor_LoadHistories( *((uint16 *)u8p_Value),
						 u8p_Value,
						 uip_Length,
						 FUNCTION_OK );
		
	    case TASK_MONITOR_PARAM_HISTORIES:
		if ((*((uint16 *)u8p_Value) == 0))
			*((uint16 *)u8p_Value) = m_t_HistoryHeader.u16_Index;
		return TaskMonitor_LoadHistories( *((uint16 *)u8p_Value),
						 u8p_Value,
						 uip_Length,
						 FUNCTION_FAIL );
	    default:
		return FUNCTION_FAIL;
	}
	return FUNCTION_OK;
}

uint8 TaskMonitor_SensorIndex(void)
{
	return m_t_HistoryHeader.u8_SensorIndex;
}

uint TaskMonitor_SetEvent
( 
uint8 u8_Type, 
uint8 u8_Value
)
{
	uint ui_Value;
	TaskGlucose_GetConfig( TASK_GLUCOSE_PARAM_EXPIRATION,
			      (uint8*)&ui_Value,
			      0 );
	if (ui_Value != 0)
		return FUNCTION_FAIL;
	
	if ( LibQueue_GetConfig( &m_t_QueueHistory,
				LIB_QUEUE_PARAM_BUFFER_SPACE,
				(void *)&ui_Value ) != FUNCTION_OK )
		return FUNCTION_FAIL;
	if(ui_Value <= sizeof(history) )
		return FUNCTION_FAIL;
	
	m_t_History.u8_Type = u8_Type;
	m_t_History.t_Parameter.u8_value = u8_Value;
	ui_Value = sizeof(m_t_History);
	if ( LibQueue_PushTail( &m_t_QueueHistory,
			       (const uint8 *)&m_t_History,
			       &ui_Value ) != FUNCTION_OK )
		return FUNCTION_FAIL;
	
	return FUNCTION_OK;
}


uint TaskMonitor_SetRemoteEvent
( 
sint32 s32_DateTime, 
uint8 u8_Type, 
uint16 u16_Value 
)
{
	uint ui_Value;
	history t_History = {0};
	TaskGlucose_GetConfig( TASK_GLUCOSE_PARAM_EXPIRATION,
			      (uint8*)&ui_Value,
			      0 );
	if (ui_Value != 0)
		return FUNCTION_FAIL;
	
	if ( LibQueue_GetConfig( &m_t_QueueHistory,
				LIB_QUEUE_PARAM_BUFFER_SPACE,
				(void *)&ui_Value ) != FUNCTION_OK )
		return FUNCTION_FAIL;
	if(ui_Value <= sizeof(history) )
		return FUNCTION_FAIL;
	
	t_History.u8_Type = u8_Type;
	t_History.t_Parameter.u8_value = 0;
	t_History.s32_DateTime = s32_DateTime;
	t_History.t_Parameter.u16_value = u16_Value;
	ui_Value = sizeof(m_t_History);
	if ( LibQueue_PushTail( &m_t_QueueHistory,
			       (const uint8 *)&t_History,
			       &ui_Value ) != FUNCTION_OK )
		return FUNCTION_FAIL;
	
	return FUNCTION_OK;
}


uint TaskMonitor_SetEventLog
( 
uint16 u16_Type
)
{
	uint ui_Value;
	TaskGlucose_GetConfig( TASK_GLUCOSE_PARAM_EXPIRATION,
			      (uint8*)&ui_Value,
			      0 );
	if (ui_Value != 0)
		return FUNCTION_FAIL;
	
	if ( LibQueue_GetConfig( &m_t_QueueOperateRecord,
				LIB_QUEUE_PARAM_BUFFER_SPACE,
				(void *)&ui_Value ) != FUNCTION_OK )
		return FUNCTION_FAIL;
	if(ui_Value <= sizeof(operate_record) )
		return FUNCTION_FAIL;
	m_t_OperateRecord.u8_OperateType = u16_Type;
	ui_Value = sizeof(m_t_OperateRecord);
	if ( LibQueue_PushTail( &m_t_QueueOperateRecord,
			       (const uint8 *)&m_t_OperateRecord,
			       &ui_Value ) != FUNCTION_OK )
		return FUNCTION_FAIL;
	
	return FUNCTION_OK;
}


uint TaskMonitor_Reset(void)
{
	m_t_HistoryHeader.u16_Index = 0;
	
	m_t_HistoryHeader.u8_SensorIndex++;
	if (m_t_HistoryHeader.u8_SensorIndex == 0)
		m_t_HistoryHeader.u8_SensorIndex = 1;
	
	m_t_HistoryHeader.s32_RunningTime = m_s32_RunningTime;
	m_t_HistoryHeader.s32_StartTime = m_t_History.s32_DateTime - m_s32_RunningTime;
	
	if (m_t_HistoryHeader.s32_StartTime < 0)
		m_t_HistoryHeader.s32_StartTime = 0;
	
	TaskMonitor_SaveHistoryHead();
	m_t_History.u8_SensorIndex = m_t_HistoryHeader.u8_SensorIndex;
	
	return FUNCTION_OK;
}

//Private function definition   私有函数定义
static void TaskMonitor_LoadHistoryHead(void)
{
	uint ui_Result = FUNCTION_FAIL;
	history_header t_HistoryHeaderTemp = {0};
	if( Record_LoadHistoryHead(&t_HistoryHeaderTemp) == FUNCTION_OK)
	{
		if(t_HistoryHeaderTemp.u16_CRC == LibChecksum_GetChecksum16Bit((uint8 *)&t_HistoryHeaderTemp,sizeof(t_HistoryHeaderTemp)-sizeof(uint16)))
		{
			Lib_Memcpy((uint8 *)&m_t_HistoryHeader,(uint8 *)&t_HistoryHeaderTemp, sizeof(m_t_HistoryHeader));
			ui_Result = FUNCTION_OK;
		}
		
	}
	if(ui_Result == FUNCTION_FAIL)
	{
		TaskMonitor_ResetHistoryHead();
		for(uint8 i = 0; i < RECORD_SAVE_RETRY; i++ )
		{
			if(Record_SaveHistoryHead(&m_t_HistoryHeader) == FUNCTION_OK)
				break;
		}
	}
}
static void TaskMonitor_ResetHistoryHead(void)
{
	Lib_Memset((uint8 *)&m_t_HistoryHeader,0,sizeof(m_t_HistoryHeader));
	m_t_HistoryHeader.u8_SensorIndex = 1;
	
}

static void TaskMonitor_CheckHistoryHead(void)
{
	if(m_t_HistoryHeader.u8_SensorIndex == 0)
	{
		TaskMonitor_ResetHistoryHead();
		for(uint8 i = 0; i < RECORD_SAVE_RETRY; i++ )
		{
			if(Record_SaveHistoryHead(&m_t_HistoryHeader) == FUNCTION_OK)
				break;
		}
	}
}

static void TaskMonitor_SaveHistoryHead(void)
{
	for(uint8 i = 0; i < RECORD_SAVE_RETRY; i++ )
	{
		if(Record_SaveHistoryHead(&m_t_HistoryHeader) == FUNCTION_OK)
			break;
	}
}



static uint TaskMonitor_LoadHistory
(
uint16 u16_Index,
history *tp_History
)
{
	if ((u16_Index == 0) || (u16_Index > m_t_HistoryHeader.u16_Index))
		return FUNCTION_FAIL;
	
	if(Record_LoadHistory(u16_Index-1,tp_History) == FUNCTION_FAIL)
		return FUNCTION_FAIL;
	
	if (tp_History->u16_Index == 1)
	{
		tp_History->s32_DateTime = m_t_HistoryHeader.s32_StartTime;
		tp_History->u8_Type = HISTORY_TRANSMITTER_STARTUP;
	}
	else if ( tp_History->s32_DateTime < 0           ||
		 tp_History->u16_Index != u16_Index     ||
			 tp_History->u8_SensorIndex == 0        ||
				 tp_History->u8_SensorIndex != m_t_HistoryHeader.u8_SensorIndex )
	{
		Lib_Memset((uint8 *)tp_History, 0, sizeof(*tp_History));
		tp_History->u16_Index = u16_Index;
		tp_History->u8_Type = HISTORY_INVALID;
	}
	
	return FUNCTION_OK;
	
}
static uint TaskMonitor_LoadHistories
( 
uint16 u16_Index,
uint8 *u8p_Data,
uint *uip_Length,
uint ui_RawData 
)
{
	history t_History;
	sint32 s32_PrevDateTime = 0;
	uint8 u8_PrevType = 0;
	uint8 u8_PrevValue = 0;
	uint ui_Length = 0;
	uint ui_EventLength = 0;
	uint ui_Return = FUNCTION_OK;
	
	if ((u16_Index == 0) || (u16_Index > m_t_HistoryHeader.u16_Index))
		return FUNCTION_FAIL;
	
	Lib_Memcpy( u8p_Data, (const uint8 *)&u16_Index, sizeof(u16_Index));
	ui_Length = sizeof(u16_Index);
	u8p_Data += sizeof(u16_Index);
	
	uint ui_LoadLength;
	if (ui_RawData == FUNCTION_OK)
		ui_LoadLength = 26;
	else
		ui_LoadLength = 10;
	
	for (uint i=0; u16_Index<=m_t_HistoryHeader.u16_Index; i++ )
	{
		
		ui_Return = TaskMonitor_LoadHistory(u16_Index,&t_History);
		
		
		if (ui_Return != FUNCTION_OK)
			break;
		
		if (t_History.u16_Index == 1)
		{
			t_History.s32_DateTime = m_t_HistoryHeader.s32_StartTime;
			t_History.u8_Type = HISTORY_TRANSMITTER_STARTUP;
		}
		else if( t_History.s32_DateTime < 0              ||
			t_History.u16_Index != u16_Index        ||
				t_History.u8_SensorIndex == 0           ||
					t_History.u8_SensorIndex != m_t_HistoryHeader.u8_SensorIndex )
		{
			t_History.s32_DateTime = s32_PrevDateTime;
			t_History.u16_Index = u16_Index;
			t_History.u8_Type = HISTORY_INVALID;
			t_History.t_Parameter.u8_value = u8_PrevValue;
		}
		
		t_History.s32_DateTime = t_History.s32_DateTime / 10 * 10;
		if (i==0)
		{
			Lib_Memcpy( u8p_Data, (const uint8 *)&t_History.s32_DateTime, 4 );
			*(u8p_Data+4) = t_History.u8_Type;
			ui_EventLength = 5;
		}
		else
		{
			if( t_History.s32_DateTime < s32_PrevDateTime ||
			   t_History.s32_DateTime - s32_PrevDateTime > 1200 )
			{
				*(u8p_Data) = (uint8)0x7F;
				Lib_Memcpy( u8p_Data+1, (const uint8 *)&t_History.s32_DateTime, 4 );
				ui_EventLength = 5;
			}
			else
			{
				*(u8p_Data) = (uint8)( (t_History.s32_DateTime - s32_PrevDateTime) / 10 ) & 0x7F;
				ui_EventLength = 1;
			}
			
			if (t_History.u8_Type != u8_PrevType)
			{
				*(u8p_Data) |= 0x80;
				*(u8p_Data+ui_EventLength) = t_History.u8_Type;
				ui_EventLength += 1;
			}
		}
		
		if ( t_History.u8_Type == HISTORY_GLUCOSE               ||
		    t_History.u8_Type == HISTORY_GLUCOSE_RECOMMEND_CAL ||
			    t_History.u8_Type == HISTORY_HYPO                  ||
				    t_History.u8_Type == HISTORY_HYPER                 ||
					    t_History.u8_Type == HISTORY_HYPO_SETTING          ||
						    t_History.u8_Type == HISTORY_HYPER_SETTING          )
		{
			*(u8p_Data+ui_EventLength) = t_History.t_Parameter.u8_value;
			ui_EventLength += 1;
		}
		else if ( t_History.u8_Type == HISTORY_BLOOD_GLUCOSE    ||
			 t_History.u8_Type == HISTORY_CALIBRATION       )
		{
			Lib_Memcpy( u8p_Data+ui_EventLength, (const uint8 *)&t_History.t_Parameter.u16_value, 2 );
			ui_EventLength += 2;
		}
		
		if (ui_RawData == FUNCTION_OK)
		{
			switch (t_History.u8_Type) {
			    case HISTORY_GLUCOSE:
			    case HISTORY_GLUCOSE_RECOMMEND_CAL:
			    case HISTORY_GLUCOSE_INVALID:
				Lib_Memcpy( u8p_Data+ui_EventLength, (const uint8 *)&t_History.t_Parameter.t_Glucose+1, 17 );
				ui_EventLength += 17;
				break;
			    case HISTORY_IMPENDANCE:
				Lib_Memcpy( u8p_Data+ui_EventLength, (const uint8 *)&t_History.t_Parameter.t_Impedance+1, 5 );
				ui_EventLength += 5;
				break;
			    default:
				break;
			}
		}
		
		s32_PrevDateTime = t_History.s32_DateTime;
		u8_PrevType = t_History.u8_Type;
		u8_PrevValue = t_History.t_Parameter.u8_value;
		
		ui_Length += ui_EventLength;
		u8p_Data += ui_EventLength;
		u16_Index++;
		
		if (ui_Length+ui_LoadLength-2 >= MAX_HISTORIES_LENGTH)
			break;
	}
	
	if (uip_Length != (uint *)0)
		*uip_Length = ui_Length;
	
	return ui_Return;
}
static void TaskMonitor_InitHistory(void)
{
	TaskMonitor_LoadHistoryHead();
	TaskMonitor_CheckHistoryHead();
	for(uint i = 0; i < RECORD_SAVE_RETRY; i++)
	{
		TaskMonitor_LoadHistory(m_t_HistoryHeader.u16_Index-i,&m_t_History);
		if(m_t_HistoryHeader.u16_Index-i == 0 || m_t_History.u8_Type != HISTORY_INVALID)
			break;
	}
	m_t_History.u8_SensorIndex = m_t_HistoryHeader.u8_SensorIndex;
	m_t_History.s32_DateTime = m_t_HistoryHeader.s32_StartTime;
	
}
///////////////////////////////////////////////////////////////

static void TaskMonitor_LoadOperateRecordHead(void)
{
	uint ui_Result = FUNCTION_FAIL;
	operate_record_header t_OperateRecordHeaderTemp = {0};
	if( Record_LoadOperateHead(&t_OperateRecordHeaderTemp) == FUNCTION_OK)
	{
		if(t_OperateRecordHeaderTemp.u16_CRC == LibChecksum_GetChecksum16Bit((uint8 *)&t_OperateRecordHeaderTemp,sizeof(operate_record_header)-sizeof(uint16)))
		{
			Lib_Memcpy((uint8 *)&m_t_OperateRecordHeader,(uint8 *)&t_OperateRecordHeaderTemp, sizeof(operate_record_header));
			ui_Result = FUNCTION_OK;
		}
		
	}
	if(ui_Result == FUNCTION_FAIL)
	{
		Lib_Memset((uint8 *)&m_t_OperateRecordHeader,0,sizeof(operate_record_header));
		for(uint8 i = 0; i < RECORD_SAVE_RETRY; i++ )
		{
			if(Record_SaveOperateHead(&m_t_OperateRecordHeader) == FUNCTION_OK)
				break;
		}
	}
}
static void TaskMonitor_SaveOperateRecordHead(void)
{
	for(uint8 i = 0; i < RECORD_SAVE_RETRY; i++ )
	{
		if(Record_SaveOperateHead(&m_t_OperateRecordHeader) == FUNCTION_OK)
			break;
	}
}
static uint TaskMonitor_LoadOpearte
(
uint16 u16_Index,
operate_record * tp_OperateRecord
)
{
	if (u16_Index == 0)
		return FUNCTION_FAIL;
	
	if(Record_LoadOperate(u16_Index-1,tp_OperateRecord) == FUNCTION_FAIL)
		return FUNCTION_FAIL;
	
	return FUNCTION_OK;
}

static void TaskMonitor_OperateRecord(void)
{
	TaskMonitor_LoadOperateRecordHead();
}
/////////////////////////////////////////////////////////////////////////

static void TaskMonitor_UpdateDateTime
( 
uint16 u16_ClockTime
)
{
	m_t_HistoryHeader.s32_RunningTime += u16_ClockTime;
	m_t_History.s32_DateTime += u16_ClockTime;
	m_t_OperateRecord.s32_DateTime += u16_ClockTime;
}

static void TaskMonitor_UpdateHistory
( 
uint16 u16_ClockTime
)
{
	static uint ui_ElapseCount = 0;
	uint ui_Value;
	history t_History;
	if (ui_ElapseCount < UPDATE_DELAY_LONG)
	{
		ui_ElapseCount += u16_ClockTime;
	}
	else if ( m_t_History.s32_DateTime - m_t_HistoryHeader.s32_StartTime >= DP.EXPIRATION_TIME &&
		 m_t_HistoryHeader.s32_RunningTime <= DP.EXPIRATION_TIME + UPDATE_DELAY_LONG       )
	{
		TaskMonitor_SaveHistoryHead();
		ui_ElapseCount = 0;
	}
	
	ui_Value = sizeof(history);
	while(LibQueue_PopHead(&m_t_QueueHistory,
			       (uint8 *)&t_History,
			       &ui_Value )== FUNCTION_OK)
	{
		TaskMonitor_SaveHistory(&t_History);
	}
	
}

static uint TaskMonitor_SaveHistory
(
history * tp_History
)
{
	tp_History->u16_Index = m_t_HistoryHeader.u16_Index+1;
	
	if(Record_SaveHistory(tp_History->u16_Index,tp_History))
	{
		m_t_HistoryHeader.u16_Index++;
		TaskMonitor_SaveHistoryHead();
		if(tp_History->u8_Type == HISTORY_PLACEHOLDER)
		{
			// m_t_HistoryHeader.u16_Index--;
		}
		else
		{
			if ( tp_History->u8_Type == HISTORY_BLOOD_GLUCOSE ||
			    tp_History->u8_Type == HISTORY_CALIBRATION    )
				tp_History->s32_DateTime = m_t_History.s32_DateTime / 10 * 10;
			else
				tp_History->s32_DateTime = tp_History->s32_DateTime / 10 * 10;
			
			m_u8_Status[STATUS_CURRENT_TIME_OFFSET] = 0;
			Lib_Memcpy( m_u8_Status + STATUS_HISTORY_OFFSET,
				   (uint8*)tp_History,
				   8 );
			
			switch (tp_History->u8_Type) 
			{
			    case HISTORY_SENSOR_NEW:
			    case HISTORY_GLUCOSE:
			    case HISTORY_GLUCOSE_RECOMMEND_CAL:
			    case HISTORY_GLUCOSE_INVALID:
			    case HISTORY_IMPENDANCE:
				Lib_Memcpy( m_u8_Status + STATUS_VALUE_OFFSET,
					   (uint8*)tp_History + 8,
					   8 );
				break;
			    case HISTORY_CALIBRATION:
#if SENSOR_AUTOBASE
				m_u8_Status[STATUS_VALUE_OFFSET] = TaskGlucose_ClipGlucose((Glu_GetCurrentAutoBaseGlucose()+5)/10);
#else
				m_u8_Status[STATUS_VALUE_OFFSET] = TaskGlucose_ClipGlucose((Glu_GetCurrentGlucose()+5)/10);
#endif
				m_u8_Status[STATUS_TYPE_OFFSET] = HISTORY_PLACEHOLDER;
				break;
			    case HISTORY_BLOOD_GLUCOSE:
				m_u8_Status[STATUS_TYPE_OFFSET] = HISTORY_PLACEHOLDER;
				break;
			    default:
				break;
			}
			
			uint8 u8_State;
			TaskGlucose_GetConfig( TASK_GLUCOSE_PARAM_STATE,
					      &u8_State,
					      0 );
			m_u8_Status[STATUS_TYPE_OFFSET] &= TYPE_MASK;
			m_u8_Status[STATUS_TYPE_OFFSET] |= u8_State & STATE_MASK;
			
			switch (tp_History->u8_Type) {
			    case HISTORY_HYPO:
			    case HISTORY_HYPER:
			    case HISTORY_HYPO_SETTING:
			    case HISTORY_HYPER_SETTING:
				m_u8_Status[STATUS_VALUE_OFFSET+1] = tp_History->t_Parameter.u8_value;
			    case HISTORY_GLUCOSE_RECOMMEND_CAL:
			    case HISTORY_GLUCOSE_INVALID:
			    case HISTORY_IMPENDANCE:
				TaskGlucose_GetConfig( TASK_GLUCOSE_PARAM_GLUCOSE,
						      &m_u8_Status[STATUS_VALUE_OFFSET],
						      0 );
				break;
			    default:
				break;
			}
			m_ui_UpdateNow = FUNCTION_OK;
			
		}
	}
	else
		return FUNCTION_FAIL;
	
	return FUNCTION_OK;
}

static uint TaskMonitor_SaveOperateRecord
(
operate_record * tp_OperateRecord
)
{
	tp_OperateRecord->u16_Index = m_t_OperateRecordHeader.u16_Index + 1;
	if(Record_SaveOperate(tp_OperateRecord->u16_Index,tp_OperateRecord))
	{
		m_t_OperateRecordHeader.u16_Index++;
		TaskMonitor_SaveOperateRecordHead();
	}
	else
		return FUNCTION_FAIL;
	return FUNCTION_OK;
	
}

static void TaskMonitor_UpdateOperateRecord
( 
uint16 u16_ClockTime
)
{
	uint ui_Value;
	operate_record t_OperateRecord;
	ui_Value = sizeof(operate_record);
	while(LibQueue_PopHead(&m_t_QueueOperateRecord,
			       (uint8 *)&t_OperateRecord,
			       &ui_Value )== FUNCTION_OK)
	{
		//TaskMonitor_SaveHistory(&t_History);
		
	}
}

uint TaskMonitor_UpdateBattery(void)
{
	
	uint16 u16_Value;
	u16_Value = Battery_Voltage();
	m_u8_Status[STATUS_BATTERY_OFFSET] = (uint8)(u16_Value-100);
	return u16_Value;
}


static void TaskMonitor_Update
( 
uint16 u16_ClockTime 
)
{
	static uint8 u8_addTime = 0;

	TaskMonitor_UpdateDateTime(u16_ClockTime);
	TaskMonitor_UpdateHistory(u16_ClockTime);
	TaskMonitor_UpdateOperateRecord(u16_ClockTime );
	
	sint32 s32_addTime = m_t_History.s32_DateTime - (m_u8_Status[STATUS_DATETIME_OFFSET+3]<<24 |
	m_u8_Status[STATUS_DATETIME_OFFSET+2]<<16 | m_u8_Status[STATUS_DATETIME_OFFSET+1]<<8 | 
	m_u8_Status[STATUS_DATETIME_OFFSET+0] ) ;
//	sint32 s32_addTime = m_t_History.s32_DateTime - *(sint32*)(m_u8_Status+STATUS_DATETIME_OFFSET);
	if (s32_addTime < 0)
		s32_addTime = 0;
	if (s32_addTime > 2400)
		s32_addTime = 2400;
	u8_addTime = (uint8)(s32_addTime/10);
	if (m_u8_Status[STATUS_CURRENT_TIME_OFFSET] != u8_addTime)
	{
		m_u8_Status[STATUS_CURRENT_TIME_OFFSET] = u8_addTime;
		m_ui_UpdateNow = FUNCTION_OK;
	}
	
	if (m_ui_UpdateNow == FUNCTION_OK)
	{
		TaskMonitor_UpdateBattery();
		TaskMonitor_UpdateBroadcast();
	}
}



static void TaskMonitor_UpdateBroadcast(void)
{
	uint8 u8_Status[STATUS_SIZE];
	
	if (REG_GET_BIT(m_ui_Flag, TASK_MONITOR_FLAG_BLANK) != 0)
	{
		Lib_Memset( u8_Status, 0, STATUS_SIZE );
		TaskComm_SetConfig( TASK_COMM_PARAM_BROADCAST_DATA,
				   u8_Status,
				   STATUS_SIZE );
		return;
	}
	
	if (REG_GET_BIT(m_ui_Flag, TASK_MONITOR_FLAG_ERROR) != 0)
	{
		Lib_Memset( u8_Status, 0, STATUS_SIZE );
		u8_Status[STATUS_TYPE_OFFSET] = HISTORY_TRANSMITTER_ERROR;
		TaskComm_SetConfig( TASK_COMM_PARAM_BROADCAST_DATA,
				   u8_Status,
				   STATUS_SIZE );
		return;
	}
	
	sint16 s16_Time;
	TaskGlucose_GetConfig( TASK_GLUCOSE_PARAM_INIT_COUNT_DOWN,
			      (uint8*)&s16_Time,
			      0 );
	
	if (s16_Time == 0)
	{
		TaskComm_SetConfig( TASK_COMM_PARAM_BROADCAST_DATA,
				   m_u8_Status,
				   STATUS_SIZE );
		return;
	}
	
	
	if (s16_Time > 0)
		s16_Time = (s16_Time + 59) / SECONDS_PER_MINUTE;
	Lib_Memcpy( u8_Status, m_u8_Status, STATUS_TYPE_OFFSET );
	u8_Status[STATUS_TYPE_OFFSET] = HISTORY_SENSOR_NEW;
	u8_Status[STATUS_VALUE_OFFSET] = (uint8)s16_Time;
	TaskComm_SetConfig( TASK_COMM_PARAM_BROADCAST_DATA,
			   u8_Status,
			   STATUS_SIZE );
	
}